package com.zjun.demo.experimentaldemo.gallery_monitoring

import android.content.res.Resources
import android.graphics.Canvas
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

class StickyHeaderDecoration(
    private val adapter: EventAdapter,
    private val headerHeight: Int = 80.dpToPx() // 假设有扩展函数 dpToPx()
) : RecyclerView.ItemDecoration() {

    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(c, parent, state)

        // 1. 获取屏幕顶部可见的第一个子View
        val topChild = parent.findChildViewUnder(parent.paddingLeft.toFloat(), parent.paddingTop.toFloat()) ?: return
        val topPosition = parent.getChildAdapterPosition(topChild)
        if (topPosition == RecyclerView.NO_POSITION) return

        // 2. 获取当前需要固定的Header View
        val currentHeader = getHeaderViewForPosition(topPosition, parent) ?: return

        // 3. 测量并布局Header
        layoutHeader(currentHeader, parent)

        // 4. 计算Header的接触点
        val contactPoint = currentHeader.bottom
        val childInContact = getChildInContact(parent, contactPoint) ?: return

        // 5. 判断是否需要推动Header
        if (isHeader(childInContact, parent)) {
            moveHeader(c, currentHeader, childInContact)
        } else {
            drawHeader(c, currentHeader)
        }
    }

    private fun layoutHeader(header: View, parent: RecyclerView) {
        // 测量Header
        val widthSpec = View.MeasureSpec.makeMeasureSpec(parent.width, View.MeasureSpec.EXACTLY)
        val heightSpec = View.MeasureSpec.makeMeasureSpec(headerHeight, View.MeasureSpec.EXACTLY)
        header.measure(widthSpec, heightSpec)

        // 布局Header
        header.layout(0, 0, parent.width, headerHeight)
    }

    private fun getChildInContact(parent: RecyclerView, contactPoint: Int): View? {
        // 找到与Header底部接触的子View
        for (i in 0 until parent.childCount) {
            val child = parent.getChildAt(i)
            if (child.bottom > contactPoint && child.top <= contactPoint) {
                return child
            }
        }
        return null
    }

    private fun moveHeader(c: Canvas, currentHeader: View, nextHeader: View) {
        // 推动Header的效果：当下一个Header接近时，当前Header向上滑动
        c.save()
        val offset = nextHeader.top - currentHeader.bottom
        c.translate(0f, offset.toFloat())
        currentHeader.draw(c)
        c.restore()
    }

    private fun drawHeader(c: Canvas, header: View) {
        // 正常绘制固定Header
        c.save()
        c.translate(0f, 0f)
        header.draw(c)
        c.restore()
    }

    private fun isHeader(view: View, parent: RecyclerView): Boolean {
        val position = parent.getChildAdapterPosition(view)
        return adapter.getItemViewType(position) == EventAdapter.TYPE_HEADER
    }

    private fun getHeaderViewForPosition(position: Int, parent: RecyclerView): View? {
        // 找到指定位置对应的Header View
        var headerPosition = position
        while (headerPosition >= 0) {
            if (adapter.getItemViewType(headerPosition) == EventAdapter.TYPE_HEADER) {
                val holder = adapter.createViewHolder(parent, EventAdapter.TYPE_HEADER)
                adapter.onBindViewHolder(holder, headerPosition)
                fixLayoutSize(holder.itemView, parent)
                return holder.itemView
            }
            headerPosition--
        }
        return null
    }

    private fun fixLayoutSize(view: View, parent: ViewGroup) {
        // 确保Header正确测量
        val widthSpec = View.MeasureSpec.makeMeasureSpec(
            parent.width, View.MeasureSpec.EXACTLY
        )
        val heightSpec = View.MeasureSpec.makeMeasureSpec(
            parent.height, View.MeasureSpec.UNSPECIFIED
        )

        val childWidth = ViewGroup.getChildMeasureSpec(
            widthSpec,
            parent.paddingLeft + parent.paddingRight,
            view.layoutParams.width
        )
        val childHeight = ViewGroup.getChildMeasureSpec(
            heightSpec,
            parent.paddingTop + parent.paddingBottom,
            view.layoutParams.height
        )

        view.measure(childWidth, childHeight)
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)
    }
}

// dp转px扩展函数
fun Int.dpToPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()